package com.zego.example.videoplayerdemo.slice;

import com.zego.example.videoplayerdemo.ResourceTable;
import com.zego.example.videoplayerdemo.utils.LogUtil;
import com.zego.example.videoplayerdemo.utils.TimeUtil;
import com.zego.example.videoplayerdemo.utils.VideoElementManager;
import com.zego.example.videoplayerdemo.utils.VideoPlayerPlugin;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.agp.components.surfaceprovider.SurfaceProvider;
import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.bundle.AbilityInfo;
import ohos.media.common.sessioncore.AVElement;
import ohos.media.player.Player;

import java.util.ArrayList;
import java.util.List;

public class MainAbilitySlice extends AbilitySlice {

    private static final String TAG = MainAbilitySlice.class.getSimpleName();

    // 声明 SurfaceProvider, Surface
    // 视频渲染 view
    private SurfaceProvider surfaceProvider;
    private DirectionalLayout directionalLayout;
    private DirectionalLayout playViewLayout;
    private DirectionalLayout fullScreenPlayViewLayout;
    private Surface surface;

    private Text titleText;

    private Text currentDurationText;
    private Text totalDurationText;
    private Slider playbackProgressSlider;
    private Slider playbackVolumeSlider;

    private Button pauseButton;
    private Button resumeButton;
    private Button refreshButton;
    private RadioContainer playbackSpeedRadioContainer;

    private ListContainer listContainer;
    private List<AVElement> avElements = new ArrayList<>();
    private VideoElementsListItemProvider videoElementsListItemProvider;

    private VideoPlayerPlugin videoPlayerPlugin;


    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_main_ability);

        addSurfaceProvider();
        initPlayer();
        initComponents();
    }

    private void addSurfaceProvider() {
        surfaceProvider = new SurfaceProvider(this);

        if (surfaceProvider.getSurfaceOps().isPresent()) {
            surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceCallBack());
            surfaceProvider.pinToZTop(true);
        }
    }

    private void initPlayer() {
        videoPlayerPlugin = new VideoPlayerPlugin(getApplicationContext());
        setVideoPlayerEventHandler();
    }

    private void initComponents() {
        titleText = (Text) findComponentById(ResourceTable.Id_videoTitle_text);

        directionalLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_direction_layout);
        fullScreenPlayViewLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_fullScrenPlayViewLayout);
        fullScreenPlayViewLayout.setVisibility(Component.HIDE);
        playViewLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_playViewLayout);
        playViewLayout.addComponent(surfaceProvider);

        currentDurationText = (Text) findComponentById(ResourceTable.Id_currentDuration_text);
        totalDurationText = (Text) findComponentById(ResourceTable.Id_totalDuration_text);
        playbackProgressSlider = (Slider) findComponentById(ResourceTable.Id_playbackProgress_slider);
        playbackVolumeSlider = (Slider) findComponentById(ResourceTable.Id_playbackVolume_slider);
        playbackVolumeSlider.setMinValue(0);
        playbackVolumeSlider.setMaxValue(100);
        playbackVolumeSlider.setProgressValue(75);

        pauseButton = (Button) findComponentById(ResourceTable.Id_pause_button);
        resumeButton = (Button) findComponentById(ResourceTable.Id_resume_button);
        refreshButton = (Button) findComponentById(ResourceTable.Id_refreshList_button);
        playbackSpeedRadioContainer = (RadioContainer) findComponentById(ResourceTable.Id_playbackSpeed_radioContainer);
        playbackSpeedRadioContainer.mark(2);

        listContainer = (ListContainer) findComponentById(ResourceTable.Id_listContainer);

        setPlayViewEvent();
        setFullScreenPlayViewEvent();
        setPlaybackProgressSliderEvent();
        setplaybackVolumeSliderEvent();
        setPauseButtonEvent();
        setResumeButtonEvent();
        setRefreshButtonEvent();
        setPlaybackSpeedPickerEvent();
        setListContainerEvent();

        videoElementsListItemProvider = new VideoElementsListItemProvider();
    }

    private void setPlayViewEvent() {
        playViewLayout.setDoubleClickedListener(new Component.DoubleClickedListener() {
            @Override
            public void onDoubleClick(Component component) {
                directionalLayout.setVisibility(Component.HIDE);
                playViewLayout.removeAllComponents();
                fullScreenPlayViewLayout.setVisibility(Component.VISIBLE);
                fullScreenPlayViewLayout.addComponent(surfaceProvider);
            }
        });
    }

    private void setFullScreenPlayViewEvent() {
        fullScreenPlayViewLayout.setDoubleClickedListener(new Component.DoubleClickedListener() {
            @Override
            public void onDoubleClick(Component component) {
                fullScreenPlayViewLayout.setVisibility(Component.HIDE);
                fullScreenPlayViewLayout.removeAllComponents();
                directionalLayout.setVisibility(Component.VISIBLE);
                playViewLayout.addComponent(surfaceProvider);
            }
        });
    }

    private void setPlaybackProgressSliderEvent() {
        playbackProgressSlider.setValueChangedListener(new Slider.ValueChangedListener() {
            @Override
            public void onProgressUpdated(Slider slider, int i, boolean b) {

            }

            @Override
            public void onTouchStart(Slider slider) {

            }

            @Override
            public void onTouchEnd(Slider slider) {
                int position = slider.getProgress();
                videoPlayerPlugin.seekTo(position);
            }
        });
    }

    private void setplaybackVolumeSliderEvent() {
        playbackVolumeSlider.setValueChangedListener(new Slider.ValueChangedListener() {
            @Override
            public void onProgressUpdated(Slider slider, int i, boolean b) {

            }

            @Override
            public void onTouchStart(Slider slider) {

            }

            @Override
            public void onTouchEnd(Slider slider) {
                int volume = slider.getProgress();
                videoPlayerPlugin.setPlaybackVolume(volume);
            }
        });
    }

    private void setPauseButtonEvent() {
        pauseButton.setClickedListener((Component component) -> videoPlayerPlugin.pause());
    }

    private void setResumeButtonEvent() {
        resumeButton.setClickedListener((Component component) -> videoPlayerPlugin.resume());
    }

    private void setRefreshButtonEvent() {
        refreshButton.setClickedListener((Component component) -> refreshList());
    }

    private void setPlaybackSpeedPickerEvent() {
        playbackSpeedRadioContainer.setMarkChangedListener(new RadioContainer.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(RadioContainer radioContainer, int i) {
                setPlaybackSpeed(i);
            }
        });
    }

    private void setPlaybackSpeed(int i) {
        float speed = 0;
        switch (i) {
            case 0:
                speed = 0.5f;
                break;
            case 1:
                speed = 0.75f;
                break;
            case 2:
                speed = 1.0f;
                break;
            case 3:
                speed = 1.5f;
                break;
            case 4:
                speed = 2.0f;
                break;
            default:
                speed = 1.0f;
        }
        videoPlayerPlugin.setPlaybackSpeed(speed);
    }

    private void setListContainerEvent() {
        listContainer.setItemClickedListener((listRoom, component, position, l) -> play(position));
    }

    private void play(int position) {
        AVElement item = avElements.get(position);
        String itemText = item.getAVDescription().getTitle().toString();
        titleText.setText(itemText);
        videoPlayerPlugin.play(videoElementsListItemProvider.getItem(position), surface);
    }

    private void preparePlaybackUI() {
        int totalDuration = videoPlayerPlugin.getDuration();

        playbackProgressSlider.setMinValue(0);
        playbackProgressSlider.setMaxValue(totalDuration);

        String strTotalDuration = TimeUtil.stringForTime(totalDuration);

        currentDurationText.setText("00:00");
        totalDurationText.setText(strTotalDuration);

        setPlaybackSpeed(playbackSpeedRadioContainer.getMarkedButtonId());
    }

    private void refreshList() {
        VideoElementManager videoElementManager = new VideoElementManager(getApplicationContext());
        avElements = videoElementManager.getAvElements();
        listContainer.setItemProvider(videoElementsListItemProvider);
    }

    private void updatePlayerSurface() {
        if (videoPlayerPlugin == null) {
            return;
        }
        videoPlayerPlugin.updateSurface(surface);
    }

    private void setVideoPlayerEventHandler() {
        videoPlayerPlugin.setVideoPlayerEventHandler(new VideoPlayerPlugin.VideoPlayerEventHandler() {
            @Override
            public void onPrepared() {
                preparePlaybackUI();
            }

            @Override
            public void onPlaybackProgressUpdate(int millisecond) {
                playbackProgressSlider.setProgressValue(millisecond);
                String strCurrentDuration = TimeUtil.stringForTime(millisecond);
                currentDurationText.setText(strCurrentDuration);
            }

            @Override
            public void onMessage(int type, int extra) {

            }

            @Override
            public void onError(int errorType, int errorCode) {

            }

            @Override
            public void onResolutionChanged(int width, int height) {

            }

            @Override
            public void onPlayBackComplete() {

            }

            @Override
            public void onRewindToComplete() {

            }

            @Override
            public void onBufferingChange(int percent) {

            }

            @Override
            public void onNewTimedMetaData(Player.MediaTimedMetaData mediaTimedMetaData) {

            }

            @Override
            public void onMediaTimeIncontinuity(Player.MediaTimeInfo mediaTimeInfo) {

            }
        });
    }

    class SurfaceCallBack implements SurfaceOps.Callback {
        @Override
        public void surfaceCreated(SurfaceOps callbackSurfaceOps) {
            if (surfaceProvider.getSurfaceOps().isPresent()) {
                surface = surfaceProvider.getSurfaceOps().get().getSurface();
                LogUtil.info(TAG, "surface set");
            }
        }

        @Override
        public void surfaceChanged(SurfaceOps callbackSurfaceOps, int format, int width, int height) {
            LogUtil.info(TAG, "surface changed");
        }

        @Override
        public void surfaceDestroyed(SurfaceOps callbackSurfaceOps) {
            LogUtil.info(TAG, "surface destroyed");
        }
    }

    class VideoElementsListItemProvider extends BaseItemProvider {
        @Override
        public int getCount() {
            return avElements.size();
        }

        @Override
        public AVElement getItem(int position) {
            return avElements.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public Component getComponent(int position, Component component, ComponentContainer componentContainer) {
            AVElement item = avElements.get(position);
            if (component == null) {
                String itemText = item.getAVDescription().getTitle().toString();
                Text text = (Text) LayoutScatter.getInstance(MainAbilitySlice.this)
                        .parse(ResourceTable.Layout_list_item, null, false);
                text.setText(itemText);
                return text;
            } else {
                return component;
            }
        }
    }

    @Override
    protected void onOrientationChanged(AbilityInfo.DisplayOrientation displayOrientation) {
        super.onOrientationChanged(displayOrientation);
    }

    @Override
    public void onStop() {
        videoPlayerPlugin.release();
        super.onStop();
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }
}
